package com.example.kotlinpractice.compare

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.recyclerview.widget.RecyclerView

/**
 *
 * Created by dingshuhong on 2020/10/27.
 */

class RowRecyclerView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) ,
    ScrollListener,
    ScrollSourceChangedListener {

    private val scrollDispatcher: ScrollDispatcher? = null
    private val scrollSourceChangedDispatcher: ScrollSourceChangedDispatcher? = null
    private var scrollSource: RecyclerView? = null


    override fun onScrolled(dx: Int, dy: Int) {
        super.onScrolled(dx, dy)
        // 系统回调，通过ScrollDispatcher同步给其他需要联动滚动的View
        // 此回调可能是因为用户操作触发，也可能是被其他View通过ScrollDispatcher触发
        // 只有第一种情况，即自己是ScrollSource时，才需要通知外部
        // 系统回调，通过ScrollDispatcher同步给其他需要联动滚动的View
        // 此回调可能是因为用户操作触发，也可能是被其他View通过ScrollDispatcher触发
        // 只有第一种情况，即自己是ScrollSource时，才需要通知外部
        if (scrollDispatcher != null && scrollSource === this && dx != 0) {
            scrollDispatcher.dispatchScroll(
                scrollSource!!, dx, dy,
                computeHorizontalScrollOffset(),
                computeVerticalScrollOffset()
            )
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.actionMasked) {
            MotionEvent.ACTION_DOWN -> makeSelfAsScrollSource()
            MotionEvent.ACTION_CANCEL -> changeScrollSource(null, false)
        }
        return super.dispatchTouchEvent(ev)
    }

    private fun changeScrollSource(
        view: RowRecyclerView?,
        onlyStopPreviousSourceWhenPreviousNotSelf: Boolean
    ) {
        if (scrollSource != null && (scrollSource !== this || !onlyStopPreviousSourceWhenPreviousNotSelf)) {
            scrollSource!!.stopScroll()
        }
        scrollSource = view
        scrollSourceChangedDispatcher?.onScrollSourceChanged(scrollSource)
    }

    fun makeSelfAsScrollSource() {
        changeScrollSource(this, true)
    }

    override fun onScrolled(
        scrollSource: RecyclerView, dx: Int, dy: Int,
        totalScrolledX: Int, totalScrolledY: Int) {
        // 收到ScrollDispatcher通知需要同步滚动位置， 若自己是ScrollSource，不要重复滚动
        if (this === scrollSource) {
            return
        }
        if (scrollState == SCROLL_STATE_SETTLING) {
            stopScroll()
        }
        scrollBy(dx, dy)
    }

    override fun onScrollSourceChanged(scrollSource: RecyclerView?) {
        this.scrollSource = scrollSource
    }


}